package com.frejoys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frejoys.common.dto.admin.UserLevelStoreMoneyListDto;
import com.frejoys.common.dto.common.PageDto;
import com.frejoys.common.enums.EStatus;
import com.frejoys.common.enums.EStoreUserRole;
import com.frejoys.common.enums.EUserLevelType;
import com.frejoys.common.util.AppConfigUtil;
import com.frejoys.common.vo.admin.UserLevelMoneyListVo;
import com.frejoys.common.vo.admin.UserLevelStoreMoneyListVo;
import com.frejoys.common.vo.app.AgentStoreListVo;
import com.frejoys.dao.entity.*;
import com.frejoys.dao.mapper.StoreMapper;
import com.frejoys.dao.mapper.StoreUserMapper;
import com.frejoys.dao.mapper.UserLevelStoreMoneyMapper;

import com.frejoys.dao.mapper.UserMapper;
import com.frejoys.service.UserLevelStoreMoneyService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor
public class UserLevelStoreMoneyServiceImpl extends ServiceImpl<UserLevelStoreMoneyMapper, UserLevelStoreMoney> implements UserLevelStoreMoneyService {

    private final UserMapper userMapper;

    private final StoreMapper storeMapper;

    private final StoreUserMapper storeUserMapper;

    @Override
    public boolean addIfNot(Long userId, Integer storeId) {
        LambdaQueryWrapper<UserLevelStoreMoney> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(UserLevelStoreMoney::getId)
                .eq(UserLevelStoreMoney::getUserId,userId)
                .eq(UserLevelStoreMoney::getStoreId,storeId);
        UserLevelStoreMoney userLevelMoney = getOnly(wrapper);

        if (userLevelMoney == null){
            save(new UserLevelStoreMoney(){{
                setUserId(userId);
                setStoreId(storeId);
                setMoney(BigDecimal.ZERO);
            }});
        }

        return true;
    }

    @Override
    public IPage<UserLevelStoreMoneyListVo> userLevelStoreMoneyListInfo(UserLevelStoreMoneyListDto dto) {
        Page page = new Page<>(dto.getPage(), dto.getSize());

        LambdaQueryWrapper<UserLevelStoreMoney> wrapper = new LambdaQueryWrapper<>();

            if (dto.getUserId() != null){
                wrapper.eq(UserLevelStoreMoney::getUserId,dto.getUserId());
            }
            if (StrUtil.isNotEmpty(dto.getPhone())){
                Long userId = userMapper.phoneByUserId(dto.getPhone());

                if (userId == null){
                    return new Page<>();
                }
                wrapper.eq(UserLevelStoreMoney::getUserId,userId);
            }
            if (StrUtil.isNotEmpty(dto.getNickname())){
                List<Long> userIds = userMapper.nicknameByUserId(dto.getNickname());

                if (userIds.isEmpty()){
                    return new Page<>();
                }
                wrapper.in(UserLevelStoreMoney::getUserId,userIds);
            }
        if (StrUtil.isNotEmpty(dto.getStoreName())){
            List<Store> stores = storeMapper.getStoreNameById(dto.getStoreName());

            if (stores.isEmpty()){
                return new Page<>();
            }

            List<Integer> storeIds = stores.stream().map(Store::getId).toList();
            wrapper.in(UserLevelStoreMoney::getStoreId,storeIds);
        }


        Page<UserLevelStoreMoney> userLevelStoreMoneyPage = baseMapper.selectPage(page, wrapper);
        IPage<UserLevelStoreMoneyListVo> voIPage = userLevelStoreMoneyPage.convert(userLevelStoreMoney -> BeanUtil.copyProperties(userLevelStoreMoney, UserLevelStoreMoneyListVo.class));
        List<UserLevelStoreMoneyListVo> list = voIPage.getRecords();

        if (!list.isEmpty()) {
            // 推荐人id
            List<Long> userIds = list.stream().map(UserLevelStoreMoneyListVo::getUserId).distinct().toList();

            List<User> users = userMapper.getUserByIds(userIds);
            Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));

            // 店铺id
            List<Integer> storeIds = list.stream().map(UserLevelStoreMoneyListVo::getStoreId).toList();

            List<Store> stores = storeMapper.getStoreNameList(storeIds);
            Map<Integer, Store> storeMap = stores.stream().collect(Collectors.toMap(Store::getId, store -> store));

            list.forEach(vo ->{

                if (userMap.containsKey(vo.getUserId())){
                    User user = userMap.get(vo.getUserId());
                    vo.setNickname(user.getNickname());
                    vo.setAvatar(AppConfigUtil.getUrlPrefix(user.getAvatar()));
                    vo.setPhone(user.getPhone());
                }
                if (storeMap.containsKey(vo.getStoreId())){
                    Store store = storeMap.get(vo.getStoreId());
                    vo.setStoreName(store.getName());
                    vo.setLogoUrl(AppConfigUtil.getUrlPrefix(store.getLogo()));
                }
            });
        }
        return voIPage;
    }


    @Override
    public List<AgentStoreListVo> listInfo(PageDto dto, Long userId) {
        Page page = new Page<>(dto.getPage(), dto.getSize());
        page.setSearchCount(false);

        List<AgentStoreListVo> listVos= new ArrayList<>();

        //查询推广金额
        List<UserLevelStoreMoney> userLevelMonies = baseMapper.storeMoneyByUserId(page,userId);

        if (!userLevelMonies.isEmpty()){

            //推广金额
            Map<Integer, BigDecimal> childUserMoneyMap = userLevelMonies.stream().collect(Collectors.toMap(UserLevelStoreMoney::getStoreId, UserLevelStoreMoney::getMoney));


            List<Integer> storeIds = userLevelMonies.stream().map(UserLevelStoreMoney::getStoreId).toList();

            ////查询店铺拥有者
            LambdaQueryWrapper<StoreUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.select(StoreUser::getUserId,StoreUser::getStoreId).in(StoreUser::getStoreId,storeIds).eq(StoreUser::getRole, EStoreUserRole.possess.getValue());
            List<StoreUser> storeUsers = storeUserMapper.selectList(wrapper);
            Map<Integer, Long> storeUserMap = storeUsers.stream().collect(Collectors.toMap(StoreUser::getStoreId, StoreUser::getUserId));

            List<Long> userIds = storeUsers.stream().map(StoreUser::getUserId).toList();

            Map<Long, User> userMap = new HashMap<>();
            if (!userIds.isEmpty()){
                List<User> users = userMapper.getUserList(userIds, EStatus.on.getValue());
                userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));
            }

            //获取店铺信息
            List<Store> stores = storeMapper.getStoreNameList(storeIds);
            Map<Integer, Store> storeMap = stores.stream().collect(Collectors.toMap(Store::getId, store -> store));

                for (UserLevelStoreMoney userLevelStoreMoney:userLevelMonies) {
                    AgentStoreListVo vo = new AgentStoreListVo();
                    vo.setId(userLevelStoreMoney.getId());

                    //插入推广金额
                    if (childUserMoneyMap.containsKey(userLevelStoreMoney.getStoreId())){
                        vo.setChildUserMoney(childUserMoneyMap.get(userLevelStoreMoney.getStoreId()));
                    }

                    //插入店铺拥有者信息
                    if (storeUserMap.containsKey(userLevelStoreMoney.getStoreId())){
                        if (userMap.containsKey(storeUserMap.get(userLevelStoreMoney.getStoreId()))){
                            User user = userMap.get(storeUserMap.get(userLevelStoreMoney.getStoreId()));
                            vo.setNickname(user.getNickname());
                            vo.setAvatar(AppConfigUtil.getUrlPrefix(user.getAvatar()));
                            vo.setRole(user.getRole());
                        }
                    }

                    //插入店铺信息
                    if (storeMap.containsKey(userLevelStoreMoney.getStoreId())){
                        Store store = storeMap.get(userLevelStoreMoney.getStoreId());
                        vo.setName(store.getName());
                        vo.setLogo(store.getLogo());
                    }

                    listVos.add(vo);
                }
        }

        return listVos;
    }

}
